#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "axil_cmd.h"
#include <cstring>


int axil_cmd_setup(axil_cmd_handle *handle, unsigned int baseAddr) {
    handle->baseAddr=baseAddr;
    handle->axil_cmd_handler = open("/dev/mem", O_RDWR | O_SYNC);
    handle->axil_cmd_VirtualAddress = (unsigned int*)mmap(NULL, 65535, PROT_READ | PROT_WRITE, MAP_SHARED, handle->axil_cmd_handler, (off_t)handle->baseAddr);
    if(handle->axil_cmd_VirtualAddress == MAP_FAILED) {
        perror("gpioVirtualAddress mapping for absolute memory access failed.\n");
        return -1;
    }
    else
        return 0;
}

//映射的寄存器，每个功能偏移4字节
//指针为unsigned int*类型指针，每次角标变化1，偏移4字节地址，每次移动相当于移动到下一个功能的寄存器地址位置
void axil_cmd_set(axil_cmd_handle *handle, int num, unsigned int val){
    handle->axil_cmd_VirtualAddress[num>>2]=val;
}

unsigned int axil_cmd_get(axil_cmd_handle *handle, int num){
    return handle->axil_cmd_VirtualAddress[num>>2];
}

//控制写 | 寄存器号 | 写入数据
void sensor_spi_set(axil_cmd_handle *handle,int register_offset, int register_status, unsigned int TX_ADDR,unsigned int TX_DATA){
    axil_cmd_set(handle,register_offset,(((0x3<<17) | ((TX_ADDR&0x1FF) << 8)) | (TX_DATA&0xFF)));
    while(((axil_cmd_get(handle,register_status) >> 26) & 0x1) != 0);
}

/*偏移到SPI_TX_OFFSET地址的32位中（默认全为0）：
 *7:0    是数据
 *16:8  是控制器地址，如要控制103号寄存器，需要写入这里
 *17     设置位为1：写，0：读
*/

//因为低8位为数据，16:8是需要操作的寄存器，所以左移8位
unsigned int sensor_spi_get(axil_cmd_handle *handle, int register_offset, int register_status, int register_read, unsigned int RX_ADDR){
    axil_cmd_set(handle,register_offset,((RX_ADDR&0x1FF) << 8) | (0x1 << 18) | (0x0 << 17) | 0xff);
    while(((axil_cmd_get(handle,register_status) >> 26) & 0x1) != 0);
    return axil_cmd_get(handle,register_read);
}
